import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:kq_flutter_core_widget/widgets/image/kq_image.dart';
import 'package:kq_flutter_core_widget/widgets/imageBox/kq_image_box.dart';
import 'package:kq_flutter_core_widget/utils/file_preview_util.dart';
import 'package:kq_flutter_widgets/resources/kq_theme_colors.dart';

import '../../resources/l10n/kq_intl.dart';
import '../button/kq_select_button.dart';

class KqRollSwipe extends StatefulWidget {
  /// 展示的数据
  final List<ImageUrl> urls;

  /// 界面宽度
  final double? width;

  /// 界面高度
  final double? height;

  /// 是否开启自动滑动
  final bool isAutoSlide;

  ///指示器
  final IIndicator? indicator;

  ///模认图片
  final String defaultPic;

  ///是否显示主题标签 默认不展示主图标签
  final bool tagEnable;

  const KqRollSwipe(
      {super.key,
      required this.urls,
      required this.defaultPic,
      this.width,
      this.height,
      this.isAutoSlide = false,
      this.indicator,
      this.tagEnable = false});

  @override
  State<StatefulWidget> createState() => KqRollSwipeState();
}

class KqRollSwipeState<T extends ImageUrl> extends State<KqRollSwipe> {
  // static const int maxInt = 100000000;

  /// 执行自动滑动的时间间隔s
  static const int slideTime = 6;

  /// 当前正在显示的图片
  int position = 0;

  ///定时滑动计时器
  Timer? _timer;

  /// 指示器
  IIndicator? _indicator;

  /// 当Indicator的类型为widget时的widget列表值
  List<Widget>? _indicatorWidgetList;

  PageController controller = PageController();

  @override
  void initState() {
    _indicator = widget.indicator ?? DrawIndicator();
    _startSlide();
    _initWidgetIndicator(position);

    controller.addListener(() {
      if (controller.page != null) {
        if (controller.page! % 1 == 0) {
          _startSlide();
        } else {
          _timer?.cancel();
        }
      }
    });
    super.initState();
  }

  void _initWidgetIndicator(int index) {
    position = index;
    if (_indicator?.type == IndicatorType.widget) {
      _indicatorWidgetList = _indicator?.onIWidget(widget.urls.length, index);
    }
  }

  void _startSlide() {
    if (widget.isAutoSlide) {
      if (_timer == null || !_timer!.isActive) {
        //计时器，每1毫秒执行一次
        const period = Duration(seconds: slideTime);
        _timer = Timer.periodic(period, (timer) {
          if (position == widget.urls.length - 1) {
            position = 0;
          } else {
            position++;
          }
          controller.nextPage(
              duration: const Duration(milliseconds: 200), curve: Curves.ease);
        });
      }
    }
  }

  @override
  void dispose() {
    //退出时关闭计时器防止内存泄露
    _timer?.cancel();
    super.dispose();
  }

  _renderImage(int index) {
    if (widget.urls.length > index % widget.urls.length) {
      var imageUrl = widget.urls[index % widget.urls.length];
      return KqImage.custom(
        imageType: imageUrl.imageType,
        width: widget.width ?? context.width,
        height: widget.height ?? 200.r,
        url: imageUrl.url,
        backgroundColor: KqThemeColors.bgF4,
        fit: BoxFit.fitHeight,
        errorImageBuilder: (context, url, error) => ColoredBox(
          color: Colors.white,
          child: SizedBox(
              width: widget.width ?? context.width,
              height: widget.height ?? 200.r),
        ),
        placeholderBuilder: (context, url) => ColoredBox(
          color: Colors.white,
          child: SizedBox(
              width: widget.width ?? context.width,
              height: widget.height ?? 200.r),
        ),
      );
    }
    return null;
  }

  //未上传图片
  Widget _buildNoPictures() {
    return Container(
      color: const Color(0xffF4F4F5),
      width: context.width,
      height: widget.height ?? 200.r,
      alignment: Alignment.center,
      child: KqImage.assets(
        url: widget.defaultPic,
        width: 100.r,
        height: 100.r,
        fit: BoxFit.fitHeight,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: widget.height ?? 200.r,
      width: widget.width ?? context.width,
      child: widget.urls.isEmpty
          ? _buildNoPictures()
          : RepaintBoundary(
              child: Stack(
                  alignment: Alignment.center,
                  fit: StackFit.expand,
                  children: [
                  PageView.builder(
                    itemCount: widget.urls.length,
                    allowImplicitScrolling: true,
                    controller: controller,
                    onPageChanged: (index) {
                      this.position = index % widget.urls.length;
                      _initWidgetIndicator(this.position);
                      setState(() {});
                    },
                    itemBuilder: (context, index) {
                      return InkWell(
                        onTap: () {
                          ///放大图片
                          if (widget.urls.length == 1) {
                            FilePreviewUtil.previewSingleImg(widget.urls[0]);
                          } else {
                            FilePreviewUtil.previewImg(widget.urls,
                                position: position);
                          }
                        },
                        child: _renderImage(index),
                      );
                    },
                  ),
                  Visibility(
                      visible: widget.urls.length > 1,
                      child: IgnorePointer(
                        child: CustomPaint(
                          painter: _SwipeIndicatorPinter(
                              this,
                              widget.urls.length,
                              position,
                              _indicator!,
                              context.width),
                        ),
                      )),
                  Positioned(
                      bottom: 10,
                      child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: _indicatorWidgetList ?? [])),
                  Visibility(
                    visible: this.position == 0 &&
                        widget.tagEnable &&
                        widget.urls.length > 1,
                    child: Positioned(
                        left: 0,
                        top: 0,
                        child: KqSelectButton(
                          text: KqIntl.currentResource.themeHint,
                          backgroundColor: KqThemeColors.textGreen,
                          textColor: KqThemeColors.bgWhite,
                          fontSize: 12.sp,
                          padding: EdgeInsets.symmetric(
                              horizontal: 10.r, vertical: 4.r),
                        )),
                  )
                ])),
    );
  }
}

class _SwipeIndicatorPinter extends CustomPainter {
  final KqRollSwipeState state;
  final int _length;
  final int _index;
  final IIndicator _indicator;
  final double _width;

  Paint selfPaint = Paint()
    ..color = Colors.blue
    ..style = PaintingStyle.fill
    ..isAntiAlias = true
    ..strokeCap = StrokeCap.butt
    ..strokeWidth = 30.0;

  _SwipeIndicatorPinter(
      this.state, this._length, this._index, this._indicator, this._width);

  @override
  void paint(Canvas canvas, Size size) {
    if (_indicator.type == IndicatorType.draw) {
      _indicator.onIDraw(canvas, _length, _index, state.widget.width ?? _width,
          state.widget.height ?? 200.r);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

enum IndicatorType {
  /// widget类型
  widget,

  /// 绘制类型
  draw
}

/// 指示器，实现该类进行自定义绘制
abstract class IIndicator {
  final IndicatorType type;

  IIndicator(this.type);

  /// 自定义绘制
  /// length 指示器个数
  /// curIndex 指示器当前位置
  /// w 控件宽度
  /// h 控件高度
  onIDraw(Canvas canvas, int length, int curIndex, double w, double h);

  /// 自定义传widget
  /// length 指示器个数
  /// curIndex 指示器当前位置
  /// return List<Widget> 指示器列表
  List<Widget> onIWidget(int length, int curIndex);
}

/// 自定义绘制的指示器抽象类，自定义绘制的方式需要继承该类实现
/// 多种样式 多种扩展
abstract class IDrawIndicator extends IIndicator {
  IDrawIndicator() : super(IndicatorType.draw);

  @override
  onIDraw(Canvas canvas, int length, int curIndex, double w, double h) {
    onDraw(canvas, length, curIndex, w, h);
  }

  @override
  List<Widget> onIWidget(int length, int curIndex) {
    ///啥也不干
    return [];
  }

  /// 过渡方法
  onDraw(Canvas canvas, int length, int curIndex, double w, double h);
}

/// 内置绘制指示器
class DrawIndicator extends IDrawIndicator {
  /// 指示器单个点x方向偏移
  final double _dotOffsetDx = 10;

  /// 指示器单个点y方向偏移
  final double _dotOffsetDy = 10;

  /// 指示器点的半径
  final double _dotRadius = 3.r;

  /// 指示器画笔
  final Paint _paint = Paint()
    ..style = PaintingStyle.fill
    ..isAntiAlias = true
    ..strokeCap = StrokeCap.butt
    ..strokeWidth = 30.0;

  @override
  onDraw(Canvas canvas, int length, int curIndex, double w, double h) {
    for (int i = 0; i < length; i++) {
      //绘制当前指示器
      if (i == curIndex) {
        _paint.color = KqThemeColors.bgWhite;
        double centerX =
            (w / 2 - (_dotRadius * 2 + (length - 1) * _dotOffsetDx) / 2) +
                (_dotRadius * 2 + _dotOffsetDx) * i;
        double centerY = h - _dotOffsetDy;
        Rect rect = Rect.fromLTRB(
            centerX - _dotRadius * 1.5,
            centerY - _dotRadius,
            centerX + _dotRadius * 1.5,
            centerY + _dotRadius);
        RRect rRect =
            RRect.fromRectAndRadius(rect, Radius.circular(_dotRadius));
        canvas.drawRRect(rRect, _paint);
        // 绘制非当前的其它指示器
      } else {
        _paint.color = KqThemeColors.bgWhite50;
        canvas.drawCircle(
            Offset(
                (w / 2 - (_dotRadius * 2 + (length - 1) * _dotOffsetDx) / 2) +
                    (_dotRadius * 2 + _dotOffsetDx) * i,
                h - _dotOffsetDy),
            _dotRadius,
            _paint);
      }
    }
  }
}

/// 传widget的指示器抽象类，传widget的方式需要继承该类实现
abstract class IWidgetIndicator extends IIndicator {
  IWidgetIndicator() : super(IndicatorType.widget);

  @override
  onIDraw(Canvas canvas, int length, int curIndex, double w, double h) {
    ///啥也不干
  }

  @override
  List<Widget> onIWidget(int length, int curIndex) {
    return onWidget(length, curIndex);
  }

  /// 过渡方法
  List<Widget> onWidget(int length, int curIndex);
}

/// 内置widget指示器
class WidgetIndicator extends IWidgetIndicator {
  @override
  List<Widget> onWidget(int length, int curIndex) {
    List<Widget> widgets = [];
    for (int i = 0; i < length; i++) {
      if (curIndex == i) {
        widgets.add(Text(
          (i + 1).toString(),
          style:
              const TextStyle(color: Colors.red, backgroundColor: Colors.white),
        ));
      } else {
        widgets.add(Text(
          (i + 1).toString(),
          style: const TextStyle(
              color: Colors.black, backgroundColor: Colors.white),
        ));
      }
    }
    return widgets;
  }
}
